package priv.pfz.basedao.mybatis.sqlprovider;

import org.apache.ibatis.builder.annotation.ProviderContext;
import priv.pfz.basedao.Utils;
import priv.pfz.basedao.info.DaoInfo;
import priv.pfz.basedao.info.FieldInfo;
import priv.pfz.basedao.mybatis.DaoInfoCache;
import priv.pfz.basedao.sharding.ShardingInfo;
import priv.pfz.basedao.sharding.ShardingManager;
import priv.pfz.basedao.sqlbuilder.SQL;

import java.util.List;
import java.util.Map;

/**
 * UPDATE table SET a=entity.a, b=entity.b WHERE uk=entity.uk
 * @author yyjxp
 * 2024/1/28 23:55
 */
public class UpdateByUniqueKeySqlProvider extends BaseSqlProvider {

    public String provideSql(Object entity, ProviderContext context) {
        return innerProvideSql(entity, null, null, context);
    }

    public String provideShardingSql(Object entity, ShardingInfo shardingInfo, ProviderContext context) {
        return innerProvideSql(entity, "arg0", shardingInfo, context);
    }

    private String innerProvideSql(Object entity, String entityArgName, ShardingInfo shardingInfo, ProviderContext context) {
        Utils.checkNotNull(entity, "entity不能为空");
        DaoInfo daoInfo = DaoInfoCache.getDaoInfo(context.getMapperType());
        List<FieldInfo> uniqueKeyFieldInfos = daoInfo.getUniqueKeyFieldInfos();
        Utils.checkNotEmpty(uniqueKeyFieldInfos, "必须在Entity中通过@UniqueKey标注唯一键,才能使用此方法");
        Map<String, Object> valueMap = getValueMap(daoInfo, entity);
        ShardingManager shardingManager = new ShardingManager(daoInfo, shardingInfo);

        SQL sql = new SQL();
        boolean hasSet = false;
        for (FieldInfo fieldInfo : daoInfo.getFieldInfos()) {
            if (fieldInfo.isUniqueKey()) {
                continue;
            }
            if (!valueMap.containsKey(fieldInfo.getFieldName())) {
                continue;
            }
            sql.SET(getFieldEquals(entityArgName, fieldInfo));
            hasSet = true;
        }
        Utils.checkArgument(hasSet, "entity除唯一键以外字段不能全部为空");
        for (FieldInfo fieldInfo : uniqueKeyFieldInfos) {
            sql.WHERE(getFieldEquals(entityArgName, fieldInfo));
            Object value = valueMap.get(fieldInfo.getFieldName());
            Utils.checkNotNull(value, "唯一键不能为空");
            shardingManager.addShardingInfo(fieldInfo, value);
        }
        if (daoInfo.isEnableLogicDelete()) {
            sql.WHERE(getLogicDeleteWhere(daoInfo));
        }
        sql.UPDATE(shardingManager.getShardingTable());
        String sqlStr = sql.toString();
        sqlStr += shardingManager.getThirdShardingStr();
        System.out.println(sqlStr);
        return sqlStr;
    }
}
